#ifndef MODBUSRTU_H
#define MODBUSRTU_H
#include <QtSerialPort>


class ModbusRtu : public QSerialPort
{
    Q_OBJECT



public:
    ModbusRtu();

    QByteArray SendCommandByte; //发送数据

    enum DataFormat {
        ABCD,
        BADC,
        CDAB,
        DCBA
    };

    int setDataRecived;

//    QSerialPort *comPort;


    void SetDataFormat(DataFormat newdataformat) { setDataformat = newdataformat;}

    //超时时间设置，会阻塞
    void SetReceiveTimeOt(quint32 receiveTime) {setReceiveTimeOut = receiveTime;}

    void setBaudRate(QSerialPort::BaudRate tmp ) {iBaudRate = tmp;}
    void setDataBits(QSerialPort::DataBits tmp) {iDataBits = tmp;}
    void setParity(QSerialPort::Parity tmp) {iParity = tmp;}
    void setStopBits(QSerialPort::StopBits tmp) {iStopBits = tmp;}

    long iMWordStartAddr;

    //初始化串口
    void iniSerialPort(QVariant sBaudRate,QVariant sDataBits,QVariant sParity,QVariant sStopBits);


    //关闭串口
    void portClose(QSerialPort *port);

    //打开串口
    bool portOpen(QString portString);

    //搜索串口
    QStringList searchPort();

    //计算CRC校验
    QByteArray verifyCRC16(QByteArray buf,qint32 Len);

    //读取输出线圈 功能码 01H
    bool ReadOutputStatus(int iDevAdd,int iAddress,int iLength);

    //读取输出线圈返回
    QByteArray revReadOutputStatus(QByteArray& revDataRead);

    //读取输入线圈 功能码 02H
    bool ReadInputStatus(int iDevadd,int iAddress,int iLength);

    //读取输入线圈返回
    QByteArray revReadInputStatus(QByteArray& revDataRead);

    //读取保持性寄存器 功能码0x03
    bool ReadKeepReg(int iDevAdd,int iAddress,int iLength);

    QByteArray revReadKeepReg(QByteArray& revDataRead);

    //读取输入寄存器 功能码 0x04
    bool ReadInputReg(int iDevAdd,int iAddress,int iLength);

    QByteArray revReadInputReg(QByteArray& revDataRead);

    //强制单线圈 功能码0x05
    bool ForceCoil(int iDevAdd,int iAddress,bool SetValue);
    //强转单线圈返回数据校验
    bool revForceCoil(QByteArray& revDataRead);


    //预置单字保持型寄存器 功能码0x06
    bool PreSetSingleReg(quint32 iDevAdd,quint32 iAddress,short SetValue);
    //预置单字保持型寄存器返回
    bool revPreSetSingleReg(QByteArray& revDataRead);

    //预置多个寄存器 功能码10H
    bool PreSetMultiByteArray(qint16 iDevAdd,int iAddress,QByteArray SetValue);
    //返回预置多个寄存器
    bool revPreSetMultiByteArray(QByteArray& revDataRead);

//    QByteArray PreSetMultiReg(int iDevAdd,int iAddress,float SetValue);
//    QByteArray PreSetMultiReg(int iDevAdd,int iAddress,int SetValue);
//    QByteArray PreSetMultiReg(int iDevAdd,int iAddress,uint SetValue);


    bool PresetMultiRes(int iDevAdd,int iAddress,const QVector<float>& SetValue);
    bool PresetMultiRes(int iDevAdd,int iAddress,const QVector<int>& SetValue);
    bool PresetMultiRes(int iDevAdd,int iAddress,const QVector<uint>& SetValue);


    QByteArray GetByteArrayFrom32Bit(float SetValue);
    QByteArray GetByteArrayFrom32Bit(int SetValue);
    QByteArray GetByteArrayFrom32Bit(uint SetValue);

    QByteArray GetByteArrayFrom16Bit(ushort SetValue);
    bool SendReadDate();


    bool sendData(QByteArray sendByteArry);
private:




    QSerialPort::BaudRate iBaudRate;
    QSerialPort::DataBits iDataBits;
    QSerialPort::Parity iParity;
    QSerialPort::StopBits iStopBits;

    DataFormat setDataformat;

    quint32 setReceiveTimeOut;



    //比较两个字节数组是否相同
    bool ArraryEquals(QByteArray b1,QByteArray b2);

    //自定义截取字节数组
    QByteArray getByteArray(QByteArray dest,int offset,int count);


    QByteArray revDataRead;



public slots:





};

#endif // MODBUSRTU_H
